package com.processmining.controller;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.deckfour.xes.model.XLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.github.pagehelper.PageInfo;
import com.processmining.entity.Log;
import com.processmining.entity.EventLog;
import com.processmining.entity.User;
import com.processmining.service.IEventLogService;
import com.processmining.support.eventLogParse.EventLogParse;
import com.processmining.support.eventLogParse.impl.EventLogParseImpl;
import com.processmining.util.algo.SummarizeTool;
import com.processmining.util.algo.SummarizeXLog;
import com.processmining.util.exception.FileSizeException;
import com.processmining.util.request.IdList;
import com.processmining.util.response.Code;
import com.processmining.util.response.ResponseData;
import com.processmining.util.response.ResponseWithListPage;
import com.processmining.util.response.ResponseWithPayload;

/**
 * 日志管理--事件日志功能控制器
 * @author hxuhao
 *
 */
@Controller
@RequestMapping(value="/eventLog")
public class EventLogController {
	
	
	private Logger logger = LogManager.getLogger(EventLogController.class.getName());
	
	
	@Autowired
	private IEventLogService eventLogService;
	
	/**
	 * 上传事件日志文件
	 * @param eventLogFile	事件日志
	 * @param format		日志格式
	 * @param shared		是否共享
	 * @param request		
	 * @return
	 * @throws IOException 
	 * @throws FileSizeException 
	 */
	@ResponseBody
	@RequestMapping(method=RequestMethod.POST)
	public ResponseData uploadEventLog(
			@RequestParam(value="file",required=true) MultipartFile eventLogFile,
			@RequestParam(value="format",required=true) String format,
			@RequestParam(value="shared",required=true) int shared,
			HttpServletRequest request,
			HttpSession session) throws IOException, FileSizeException{
		//System.out.println("\ncontent length : " + request.getContentLength());
		//System.out.println("file : " + eventLogFile.getBytes().length);
		//System.out.println(eventLogFile.getContentType());
		//System.out.println(eventLogFile.getSize());
		User user = (User) session.getAttribute("user");
		
		
		
		if(eventLogFile.getSize()==0){
			throw new FileSizeException("事件日志大小为0");
		}
		
		
		ResponseData responseData = new ResponseData();
		Log log = new EventLog();
		log.setCreatorid(user.getId());
		log.setFormat(format);
		log.setIsshared(shared==1?true:false);
		log.setName(eventLogFile.getOriginalFilename());
		
		
		
		InputStream input = null;

		try {
			input = eventLogFile.getInputStream();
			if(eventLogService.uploadLog(input, log)){
				responseData.setCode(Code.SUCCEED);
			}else{
				responseData.setCode(Code.UNKNOWN_FAULT);
			}
		} catch (Exception e) {
			e.printStackTrace();
			responseData.setCode(Code.UNKNOWN_FAULT);
		} finally {
			try {
				input.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}


		return responseData;
		
	}
	
	

	/**
	 * 下载事件日志，浏览器弹窗
	 * @param logId		事件日志id
	 * @param response
	 */
	@RequestMapping(value="/{eventlogId}",
			produces="application/octet-stream;charset=UTF-8",
			method=RequestMethod.GET)
	public void downloadEventLog(
			@PathVariable(value="eventlogId")Integer logId,
			HttpServletResponse response){
		
		EventLog log = (EventLog) eventLogService.selectByPK(logId);
		byte[] data;
		InputStream input = null;
		try {
			input = eventLogService.downloadLog(logId);
			StringBuilder sb = new StringBuilder();
			BufferedReader reader = new BufferedReader(new InputStreamReader(input, "utf-8"));
			String line ;
			while((line = reader.readLine())!=null){
				sb.append(line+"\r\n");
				System.out.println(line);
			}
			data = sb.toString().getBytes();
			
			response.reset();
			response.setContentType("charset=UTF-8");   
	        response.setHeader("Content-Disposition", "attachment;filename=" + new String(log.getName().getBytes("utf-8"),"iso-8859-1"));   
	        response.setHeader("Content-Length", String.valueOf(data.length));
	                     
	        OutputStream outputStream = response.getOutputStream();  
		    outputStream.write(data);  
		    outputStream.flush();  
		    outputStream.close();
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if(input!=null)
					input.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		
	}
	
	/**
	 * 查看一个事件日志
	 * @param id 事件日志id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/search/{id}",method=RequestMethod.GET)
	public EventLog selectOne(@PathVariable(value="id") Integer id){
		
		EventLog log = (EventLog) eventLogService.selectByPK(id);
		return log;
		
	}
	
	/**
	 * 将一个事件日志变为公有
	 * @param eventLogId 事件日志id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/share/{id}",method=RequestMethod.GET)
	public ResponseData shareEventLog(@PathVariable(value="id") Integer eventLogId,HttpSession session){

		ResponseData response = new ResponseData();
		
		User user = (User) session.getAttribute("user");
		if(eventLogService.shareLog(eventLogId, user.getId())){
			response.setCode(Code.SUCCEED);
		}else{
			response.setCode(Code.NOT_PERMISSION);
		}
		
		return response;
		
	}
	
	/**
	 * 将一个事件日志设为私有
	 * @param eventLogId 事件日志id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/unshare/{id}",method=RequestMethod.GET)
	public ResponseData unshareEventLog(@PathVariable(value="id") Integer eventLogId,HttpSession session){
		
		ResponseData response = new ResponseData();
		
		User user = (User) session.getAttribute("user");
		if(eventLogService.unshareLog(eventLogId, user.getId())){
			response.setCode(Code.SUCCEED);
		}else{
			response.setCode(Code.NOT_PERMISSION);
		}
		
		return response;
		
	}
	
	/**
	 * 查看事件日志/搜索
	 * @param pageNum
	 * @param pageSize
	 * @param info
	 * @param session
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/listAll",method=RequestMethod.GET)
	public ResponseWithListPage<EventLog> selectAll(
			@RequestParam(value="pageNum",defaultValue="1")int pageNum,
			@RequestParam(value="pageSize",defaultValue="10")int pageSize,
			@RequestParam(value="info",required=false) String info,
			HttpSession session){
		//System.out.println("info : " + info);
		User u = (User) session.getAttribute("user");
		Integer uid = u==null?1:u.getId();
		ResponseWithListPage<EventLog> response = new ResponseWithListPage<>();
		PageInfo<EventLog> logListWithPage = eventLogService.searchByName(pageNum,pageSize,info,uid);
		response.setCode(Code.SUCCEED);
		response.setData(logListWithPage);
		return response;
		
	}
	
	/**
	 * 删除日志文件
	 * @param idList id列表
	 * @return
	 */
	@ResponseBody
	@RequestMapping(method=RequestMethod.DELETE)
	public ResponseData deleteEventLog(@RequestBody IdList idList,HttpSession session){
		ResponseData response = new ResponseData();
		User user = (User) session.getAttribute("user");
		try {
			if(eventLogService.deleteBatch(idList.getIdList(),user.getId())){
				response.setCode(Code.SUCCEED);
			}else{
				response.setCode(Code.UNKNOWN_FAULT);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			response.setCode(Code.UNKNOWN_FAULT);
		} 
		
		return response;
	}
	
	
	
	/**
	 * 查看事件日志摘要
	 * @param eventLogId
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="/getInfo/{logid}",method=RequestMethod.GET)
	public ResponseData getChiefInfo(@PathVariable(value="logid")Integer eventLogId) throws Exception{
		System.out.println("get info start1");
		EventLog eventLog = (EventLog) eventLogService.selectByPK(eventLogId);
		System.out.println("get info start2");
		InputStream input = eventLogService.downloadLog(eventLogId);
		System.out.println("get info start2");
		//InputStream input= new FileInputStream(new File("D:\\1"));
		EventLogParse parser = new EventLogParseImpl();
		XLog xlog1 = parser.eventLogParse(input);
		input.close();
		System.out.println("get info start3");
		SummarizeTool st=SummarizeXLog.summarize(xlog1);
		eventLog.setAverage(st.getAverage());
		eventLog.setProcessactivityevent(st.getProcessActivityEvent());
		eventLog.setTotaleventnum(st.getTotalEventNum());
		eventLog.setTotalinstancenum(st.getTotalInstanceNum());
		eventLog.setController(st.getController());
		
		eventLogService.updateLog(eventLog);

		System.out.println("get info fin");
		ResponseWithPayload reponse = new ResponseWithPayload(Code.SUCCEED, eventLog);
		return reponse;
		
	}
	
	
	
	  
	/**
	 * 批量下载
	 * @param request
	 * @param response
	 * @param reportId
	 * @return
	 * @throws IOException
	 */
	@ResponseBody
	@RequestMapping(value="/downloadBatch",method=RequestMethod.GET)
	public String downloadBatch(HttpServletRequest request,HttpServletResponse response,
			@RequestParam(value="idList")String ids,HttpSession session) throws IOException{
		
	    String[] idList = ids.split(";");
		
		//User user = (User) session.getAttribute("user");
	    String outFilePath = request.getSession().getServletContext().getRealPath("/");
		String fileName = UUID.randomUUID()+".zip";
	    byte[] buffer = new byte[1024];   
	    try {  
	        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outFilePath+fileName),Charset.forName("UTF-8"));
	        

	        for(int i=0;i<idList.length;i++){
	        	Integer rawLogid = Integer.valueOf(idList[i]);
	            InputStream fis = eventLogService.downloadLog(rawLogid);  
	            out.putNextEntry(new ZipEntry((i+1)+"."+eventLogService.selectByPK(rawLogid).getName()));  
	            //设置压缩文件内的字符编码，不然会变成乱码  
	           
	            int len;  
	            // 读入需要下载的文件的内容，打包到zip文件  
	            while ((len = fis.read(buffer)) > 0) {  
	                out.write(buffer, 0, len);  
	            }  
	            out.closeEntry();  
	            fis.close();  
	        }  
	        out.close();  
	        this.downloadFileHelp(outFilePath,fileName,response);  
	    } catch (Exception e) {  
	     e.printStackTrace();
	    }  
	    return null;  
	}
		
		
	public void downloadFileHelp(String path,String fileName,HttpServletResponse response){  
        response.setCharacterEncoding("utf-8");  
        response.setContentType("multipart/form-data");  
  
        response.setHeader("Content-Disposition", "attachment;fileName="+fileName+".zip");  
        try {  
            File file=new File(path+fileName);  
            //System.out.println(file.getAbsolutePath());  
            InputStream inputStream=new FileInputStream(file);  
            OutputStream os=response.getOutputStream();  
            byte[] b=new byte[1024];  
            int length;  
            while((length=inputStream.read(b))>0){  
                os.write(b,0,length);  
            }  
            inputStream.close();  
            file.delete();
            
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
	
		
		
		
}
